import sharp from "sharp";
import fs from "fs/promises";
import path from "path";
import { v4 as uuidv4 } from "uuid";

interface ProcessedImage {
  picture: string;
  thumbnail: string;
}

export class ImageService {
  private static readonly UPLOAD_DIR = path.join(
    process.cwd(),
    "public",
    "uploads"
  );
  private static readonly PICTURE_DIR = path.join(this.UPLOAD_DIR, "picture");
  private static readonly THUMBNAIL_DIR = path.join(this.UPLOAD_DIR, "thumb");

  /**
   * 初始化上传目录
   */
  private static async ensureDirectories(): Promise<void> {
    try {
      await fs.access(this.PICTURE_DIR);
    } catch {
      await fs.mkdir(this.PICTURE_DIR, { recursive: true });
    }

    try {
      await fs.access(this.THUMBNAIL_DIR);
    } catch {
      await fs.mkdir(this.THUMBNAIL_DIR, { recursive: true });
    }
  }

  /**
   * 生成唯一文件名（使用UUID防止重名）
   */
  private static generateUniqueFilename(originalname: string): string {
    return `${uuidv4()}.webp`;

    const ext = path.extname(originalname);
    console.log("🚀 ~ ImageService ~ generateUniqueFilename ~ ext:", ext);

    const baseName = path.basename(originalname, ext);
    console.log(
      "🚀 ~ ImageService ~ generateUniqueFilename ~ baseName:",
      baseName
    );
    const uuid = uuidv4();
    return `${baseName}_${uuid}.webp`;
  }

  /**
   * 处理图片并转换为webp格式
   */
  private static async processImage(
    buffer: Buffer,
    filename: string,
    maxWidth: number,
    maxHeight: number,
    quality: number = 80
  ): Promise<string> {
    const outputPath = path.join(this.PICTURE_DIR, filename);

    await sharp(buffer)
      .resize({
        width: maxWidth,
        height: maxHeight,
        fit: "inside",
        withoutEnlargement: true,
      })
      .webp({ quality })
      .toFile(outputPath);

    return `/uploads/picture/${filename}`;
  }

  /**
   * 生成缩略图并转换为webp格式
   */
  private static async generateThumbnail(
    buffer: Buffer,
    filename: string,
    quality: number = 70
  ): Promise<string> {
    const thumbnailFilename = `thumb_${filename}`;
    const outputPath = path.join(this.THUMBNAIL_DIR, thumbnailFilename);

    await sharp(buffer)
      .resize({
        width: 300,
        height: 300,
        fit: "cover",
      })
      .webp({ quality })
      .toFile(outputPath);

    return `/uploads/thumb/${thumbnailFilename}`;
  }

  /**
   * 上传并处理图片
   */
  public static async uploadAndProcessImage(
    buffer: Buffer,
    originalname: string
  ): Promise<ProcessedImage> {
    await this.ensureDirectories();

    // 生成唯一文件名（防止重名）
    const uniqueFilename = this.generateUniqueFilename(originalname);

    // 处理大图
    const picturePath = await this.processImage(
      buffer,
      uniqueFilename,
      1200,
      1200,
      85
    );

    // 生成缩略图
    const thumbnailPath = await this.generateThumbnail(
      buffer,
      uniqueFilename,
      75
    );

    return {
      picture: picturePath,
      thumbnail: thumbnailPath,
    };
  }

  /**
   * 删除图片文件
   */
  public static async deleteImage(
    pictureUrl: string,
    thumbnailUrl: string
  ): Promise<void> {
    try {
      const picturePath = path.join(process.cwd(), "public", pictureUrl);
      const thumbnailPath = path.join(process.cwd(), "public", thumbnailUrl);

      await Promise.allSettled([
        fs.unlink(picturePath).catch(() => {}),
        fs.unlink(thumbnailPath).catch(() => {}),
      ]);
    } catch (error) {
      console.error("删除图片失败:", error);
    }
  }
}
